<?php
defined('IN_MY_PHP') || die(0);

/**
 * Captcha Class base on PHP GD Lib
 * @author Design
 * @version 1.0
 * @copyright js8.in 2010
 * @example
 * $captchaDemo=new Captcha();
 * $captchaDemo->createImage();
 */
class Captcha
{
	/** 定义验证码图片高度 */
	private $height;
	/** 定义验证码图片宽度 */
	private $width;
	/** 定义验证码字符个数 */
	private $textNum;
	/** 定义验证码字符内容 */
	private $textContent;
	/** 定义字符颜色 */
	private $fontColor;
	/** 定义随机出的文字颜色 */
	private $randFontColor;
	/** 定义字体大小 */
	private $fontSize;
	/** 定义字体 */
	private $fontFamily;
	/** 定义背景颜色 */
	private $bgColor;
	/** 定义随机出的背景颜色 */
	private $randBgColor;
	/** 定义字符语言 */
	private $textLang;
	/** 定义干扰点数量 */
	private $noisePoint;
	/** 定义干扰线数量 */
	private $noiseLine;
	/** 定义是否扭曲 */
	private $distortion;
	/** 定义扭曲图片源 */
	private $distortionImage;
	/** 定义是否有边框 */
	private $showBorder;
	/** 定义验证码图片源 */
	private $image;

	/** Constructor 构造函数 */
	public function __construct()
	{
		$this->textNum    = 4;
		$this->fontSize   = 16;
		$this->fontFamily = rtrim(dirname(__FILE__), DS)  . DS . 'captcha-yrd.ttf';
		$this->textLang   = 'en';
		$this->noisePoint = 30;
		$this->noiseLine  = 3;
		$this->distortion = false;
		$this->showBorder = false;
	}


	/** 设置图片宽度 */
	public function setWidth($w)
	{
		$this->width = $w;
	}

	/** 设置图片高度 */
	public function setHeight($h)
	{
		$this->height = $h;
	}

	/** 设置字符个数 */
	public function setTextNumber($textN)
	{
		$this->textNum = $textN;
	}

	/** 设置字符颜色 */
	public function setFontColor($fc)
	{
		$this->fontColor = sscanf($fc, '#%2x%2x%2x');
	}

	/** 设置字号 */
	public function setFontSize($n)
	{
		$this->fontSize = $n;
	}

	/** 设置字体 */
	public function setFontFamily($ffUrl)
	{
		$this->fontFamily = $ffUrl;
	}

	/** 设置字符语言 */
	public function setTextLang($lang)
	{
		$this->textLang = $lang;
	}

	/** 设置图片背景 */
	public function setBgColor($bc)
	{
		$this->bgColor = sscanf($bc, '#%2x%2x%2x');
	}

	/** 设置干扰点数量 */
	public function setNoisePoint($n)
	{
		$this->noisePoint = $n;
	}

	/** 设置干扰线数量 */
	public function setNoiseLine($n)
	{
		$this->noiseLine = $n;
	}

	/** 设置是否扭曲 */
	public function setDistortion($b)
	{
		$this->distortion = $b;
	}

	/** 设置是否显示边框 */
	public function setShowBorder($border)
	{
		$this->showBorder = $border;
	}

	/** 初始化验证码图片 */
	public function initImage()
	{
		if ($this->width == null) {
			$this->width = floor($this->fontSize * 1.3) * $this->textNum + 10;
		}
		if ($this->height == null) {
			$this->height = $this->fontSize * 2;
		}
		$this->image = imagecreatetruecolor($this->width, $this->height);
		if (empty($this->bgColor)) {
			$this->randBgColor = imagecolorallocate($this->image, rand(144, 255), rand(144, 255), rand(144, 255));
		} else {
			$this->randBgColor = imagecolorallocate($this->image, $this->bgColor[0], $this->bgColor[1], $this->bgColor[2]);
		}
		imagefill($this->image, 0, 0, $this->randBgColor);
	}

	/** 产生随机字符 */
	public function randText($type)
	{
		$string = '';
		switch ($type) {
			case 'en':
				$str = 'ABCDEFGHJKLMNPQRSTUVWXY3456789';
				for ($i = 0; $i < $this->textNum; $i++) {
					$string = $string . ',' . $str[rand(0, 29)];
				}
				break;
			case 'cn':
				for ($i = 0; $i < $this->textNum; $i++) {
					$string = $string . ',' . chr(rand(0xB0, 0xCC)) . chr(rand(0xA1, 0xBB));
				}
				$string = iconv('GB2312', 'UTF-8', $string); //转换编码到utf8
				break;
		}
		return substr($string, 1);
	}

	/** 输出文字到验证码 */
	public function createText()
	{
		$textArray         = explode(',', $this->randText($this->textLang));
		$this->textContent = join('', $textArray);
		if ($this->fontColor != null) {
			$this->randFontColor = imagecolorallocate($this->image, $this->fontColor[0], $this->fontColor[1], $this->fontColor[2]);
		}
		$_x = $this->width *0.9 / $this->textNum;
		$x_offset = $_x / 2 - $this->fontSize * 0.4 + $this->width * 0.05;
		$y = ($this->height + $this->fontSize) / 2;
		file_put_contents('a.txt',$y );
		for ($i = 0; $i < $this->textNum; $i++) {
			if ($this->fontColor == null) {
				$this->randFontColor = imagecolorallocate($this->image, rand(0, 100), rand(0, 100), rand(0, 100));
			}
			$angle = (rand(0, 1)==1)? rand(0, 20) : rand(-20, 0);
			imagettftext($this->image, $this->fontSize, $angle,  $_x * $i + $x_offset, $y, $this->randFontColor, $this->fontFamily, $textArray[$i]);
		}
	}

	/** 生成干扰点 */
	public function createNoisePoint()
	{
		for ($i = 0; $i < $this->noisePoint; $i++) {
			$pointColor = imagecolorallocate($this->image, rand(0, 255), rand(0, 255), rand(0, 255));
			imagesetpixel($this->image, rand(0, $this->width), rand(0, $this->height), $pointColor);
		}

	}

	/** 产生干扰线 */
	public function createNoiseLine()
	{
		for ($i = 0; $i < $this->noiseLine; $i++) {
			$lineColor = imagecolorallocate($this->image, rand(80, 224), rand(80, 224), rand(80, 224));
			imageline($this->image, 0, rand(0, $this->width), $this->width, rand(0, $this->height), $lineColor);
		}
	}

	/** 扭曲文字 */
	public function distortionText()
	{
		$this->distortionImage = imagecreatetruecolor($this->width, $this->height);
		imagefill($this->distortionImage, 0, 0, $this->randBgColor);
		$scale = (rand(0,1)==1)? rand(1, 3) : rand(-3, -1);
		for ($x = 0; $x < $this->width; $x++) {
			for ($y = 0; $y < $this->height; $y++) {
				$rgbColor = imagecolorat($this->image, $x, $y);
				imagesetpixel($this->distortionImage, (int) ($x + sin($y / $this->height * 2 * M_PI - M_PI * 0.5) * $scale), $y, $rgbColor);
			}
		}
		$this->image = $this->distortionImage;
	}

	/** 生成验证码图片 */
	public function createImage()
	{
		$this->initImage(); //创建基本图片
		$this->createText(); //输出验证码字符
		if ($this->distortion) {
			$this->distortionText();
		} //扭曲文字
		$this->createNoisePoint(); //产生干扰点
		$this->createNoiseLine(); //产生干扰线
		if ($this->showBorder) {
			imagerectangle($this->image, 0, 0, $this->width - 1, $this->height - 1, $this->randFontColor);
		} //添加边框
		imagepng($this->image);
		imagedestroy($this->image);
		if ($this->distortion && is_resource($this->distortion)) {
			imagedestroy($this->$distortionImage);
		}
		return $this->textContent;
	}

}

/** 使用方法 */
// $captcha = new Captcha();

/** 设置验证码宽度 */
// $captcha->setWidth(200);

/** 设置验证码高度 */
// $captcha->setHeight(50);

/** 设置字符个数 */
// $captcha->setTextNumber(5);

/** 设置字符颜色 */
// $captcha->setFontColor('#ff9900');

/** 设置字号大小 */
// $captcha->setFontSize(25);

/** 设置字体 */
// $captcha->setFontFamily('c:\windows\fonts\STXINGKA.TTF');

/** 设置语言(中文：cn需要设置中文字体,英文：en) */
// $captcha->setTextLang('cn');

/** 设置背景颜色 */
// $captcha->setBgColor('#000000');

/** 设置干扰点数量 */
// $captcha->setNoisePoint(600);

/** 设置干扰线数量 */
// $captcha->setNoiseLine(10);

/** 设置是否扭曲 */
// $captcha->setDistortion(true);

/** 设置是否显示边框 */
// $captcha->setShowBorder(true);

/** 输出验证码 */
// header("Cache-Control: max-age=1, s-maxage=1, no-cache, must-revalidate");
// header("Content-type: image/png;charset=utf-8");
// $code = $captcha->createImage();

?>
